﻿using System;
using System.Collections.Generic;
using System.IO;
using CtefCrmImport.Common.Interfaces;

namespace CtefCrmImport
{
    public class FileParser<T> : IFileParser<T>
    {
        private readonly string filePath;
        private readonly int headerRowCount;
        private readonly ILogger logger;
        private readonly IEntityBuilder<T> builder;

        public FileParser(string filePath, int headerRowCount, ILogger logger, IEntityBuilder<T> builder)
        {
            if (string.IsNullOrWhiteSpace(filePath) || !File.Exists(filePath.Trim()))
            {
                throw new ArgumentException("Invalid file path.", "filePath");
            }

            if (headerRowCount < 0)
            {
                throw new ArgumentException("Invalid header row count.", "headerRowCount");
            }

            if (logger == null)
            {
                throw new ArgumentNullException("logger");
            }

            if (builder == null)
            {
                throw new ArgumentNullException("donationBuilder");
            }

            this.filePath = filePath;
            this.headerRowCount = headerRowCount;
            this.logger = logger;
            this.builder = builder;
        }

        public IEnumerable<T> ParseEntities()
        {
            var result = new List<T>();
            var lineNum = 0;

            using (var reader = new StreamReader(filePath))
            {
                // skip header rows
                for (var i = 0; i < headerRowCount; i++)
                {
                    reader.ReadLine();
                    lineNum++;
                }

                try
                {
                    while (!reader.EndOfStream)
                    {
                        lineNum++;
                        var line = reader.ReadLine();
                        if (string.IsNullOrWhiteSpace(line)) continue;

                        result.Add(builder.BuildEntity(line));
                    }
                }
                catch (Exception ex)
                {
                    result = new List<T>();
                    logger.Log("Error when process line {0} in file {1}", lineNum, filePath);
                    logger.Log("Error message: {0}", ex.Message);
                    logger.Log(ex.StackTrace);
                }
            }

            logger.Log("Number of records loaded: {0}", result.Count);
            return result;
        }
    }
}
